package com.tomato.service;

import com.tomato.dto.LoginDTO;
import com.tomato.dto.RegisterDTO;
import com.tomato.dto.UserUpdateDTO;
import com.tomato.entity.User;
import com.tomato.mapper.TodoRecordMapper;
import com.tomato.mapper.TodoSettingMapper;
import com.tomato.mapper.UserMapper;
import com.tomato.util.JwtUtil;
import com.tomato.util.Md5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;
    private final TodoSettingMapper todoSettingMapper;
    private final TodoRecordMapper todoRecordMapper;
    private final JwtUtil jwtUtil;

    public UserServiceImpl(UserMapper userMapper,
                           TodoSettingMapper todoSettingMapper,
                           TodoRecordMapper todoRecordMapper,
                           JwtUtil jwtUtil) {
        this.userMapper = userMapper;
        this.todoSettingMapper = todoSettingMapper;
        this.todoRecordMapper = todoRecordMapper;
        this.jwtUtil = jwtUtil;
    }

    @Override
    public String login(LoginDTO loginDTO) {
        log.debug("Attempting login for phone: {}", loginDTO.getPhone());
        User user = userMapper.selectByPhone(loginDTO.getPhone());
        if (user == null || !user.getPasswordHash().equals(Md5Util.md5(loginDTO.getPassword()))) {
            log.warn("Login failed for phone: {}", loginDTO.getPhone());
            throw new RuntimeException("手机号或密码错误");
        }
        log.info("User logged in successfully: {}", user.getId());
        return jwtUtil.generateToken(user.getId());
    }

    @Override
    public Long register(RegisterDTO registerDTO) {
        log.debug("Attempting to register new user with phone: {}", registerDTO.getPhone());
        if (userMapper.selectByPhone(registerDTO.getPhone()) != null) {
            log.warn("Registration failed - phone already exists: {}", registerDTO.getPhone());
            throw new RuntimeException("手机号已存在");
        }

        User user = new User();
        BeanUtils.copyProperties(registerDTO, user);
        user.setPasswordHash(Md5Util.md5(registerDTO.getPassword()));

        userMapper.insert(user);
        log.info("New user registered successfully: {}", user.getId());
        return user.getId();
    }

    @Transactional
    @Override
    public void deleteUser(Long userId) {
        log.debug("Deleting user and all related data: {}", userId);
        // 删除关联记录（不再检查返回值）
        todoSettingMapper.deleteByUserId(userId);
        todoRecordMapper.deleteByUserId(userId);
        // 删除用户
        if (userMapper.deleteById(userId) == 0) {
            throw new RuntimeException("用户不存在或删除失败");
        }

        log.info("User deleted successfully: {}", userId);
    }

    @Override
    public void updateUser(Long userId, UserUpdateDTO updateDTO) {
        log.debug("Updating user info: {}", userId);
        User user = userMapper.selectById(userId);
        if (user == null) {
            log.error("User not found for update: {}", userId);
            throw new RuntimeException("用户不存在");
        }

        if (updateDTO.getUsername() != null) {
            user.setUsername(updateDTO.getUsername());
        }
        if (updateDTO.getNewPassword() != null) {
            if (!user.getPasswordHash().equals(Md5Util.md5(updateDTO.getOldPassword()))) {
                log.warn("Password update failed - old password mismatch for user: {}", userId);
                throw new RuntimeException("旧密码不正确");
            }
            user.setPasswordHash(Md5Util.md5(updateDTO.getNewPassword()));
        }

        userMapper.updateById(user);
        log.info("User info updated successfully: {}", userId);
    }

    @Override
    public User getCurrentUser(Long userId) {
        log.debug("Fetching current user info: {}", userId);
        return userMapper.selectById(userId);
    }

    @Override
    public String uploadAvatar(Long userId, String avatarPath) {
        log.debug("Updating avatar for user: {}", userId);
        userMapper.updateAvatar(userId, avatarPath);
        log.info("Avatar updated for user: {}", userId);
        return avatarPath;
    }
}